package com.qumap.editmap;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.maps.client.base.HasLatLng;
import com.google.gwt.maps.client.event.Event;
import com.google.gwt.maps.client.event.EventCallback;
import com.google.gwt.maps.client.overlay.HasMarker;
import com.google.gwt.user.client.ui.*;
import com.qumap.map.Map;
import com.qumap.map.TypedItemHolder;
import com.qumap.item.ItemOnMap;
import com.qumap.common.edit.IDisplay;
import com.qumap.common.event.GlobalEvent;
import com.qumap.common.event.GlobalEventCollection;
import com.qumap.common.event.GlobalEventHandler;
import com.qumap.item.event.ItemEventCollection;
import com.qumap.item.event.ItemEvent;
import com.qumap.item.event.ItemEventHandler;

import java.util.Collection;


/**
 * Created by IntelliJ IDEA.
 * User: Admin
 * Date: 06.05.11
 * Time: 15:54
 * To change this template use File | Settings | File Templates.
 */
public class EditMap extends Map implements IDisplay {


    private class SaveUpdateHandler implements ItemEventHandler {

        @Override
        public void onItemEvent(ItemEvent event) {
           processSavedOrUpdatedItem(event.getFirstItem());
        }
    }

    public EditMap() {
        setNeedClearOnLoad(false);
    }

    @Override
	protected void initListeners() {
		super.initListeners();
		global_event_bus.addHandler(ItemEventCollection.EventType.Created.getType(), new ItemEventHandler() {
			@Override
			public void onItemEvent(ItemEvent event) {
    			addCreatedItem(event.getFirstItem());
			}
		});

        SaveUpdateHandler save_update_handler = new SaveUpdateHandler();
        global_event_bus.addHandler(ItemEventCollection.EventType.Saved.getType(), save_update_handler);
        global_event_bus.addHandler(ItemEventCollection.EventType.Updated.getType(), save_update_handler);

        global_event_bus.addHandler(GlobalEventCollection.EventType.ShowUnsaved.getType(), new GlobalEventHandler() {
            @Override
            public void onGlobalEvent(GlobalEvent event) {
                showUnSavedItems();
            }
        });
	}

    protected void showUnSavedItems() {

        Collection<TypedItemHolder> all_item_holders = getAllItemHolders();
        animateMarkers(all_item_holders);
        stopMarkerAnimation(all_item_holders);

    }

    private void animateMarkers(Collection<TypedItemHolder> item_holder_collection) {

        HasMarker operate_marker;
        for(TypedItemHolder item_holder: item_holder_collection)
            for(ItemOnMap item_to_animate: item_holder.getAllItems()) {
                if(item_to_animate.hasChanges()) {
                    operate_marker = item_holder.getItemMarker(item_to_animate);
                    animate(operate_marker.getJso());
                }
            }
    }

    private native void animate(JavaScriptObject marker) /*-{
        marker.setAnimation($wnd.google.maps.Animation.BOUNCE);
    }-*/;

    private void stopMarkerAnimation(Collection<TypedItemHolder> item_holder_collection) {
        HasMarker operate_marker;
        for(TypedItemHolder item_holder: item_holder_collection)
            for(ItemOnMap item_to_animate: item_holder.getAllItems()) {
                if(item_to_animate.hasChanges()) {
                    operate_marker = item_holder.getItemMarker(item_to_animate);
                    stopAnimate(operate_marker.getJso());
                }
            }
    }

    private native void stopAnimate(JavaScriptObject marker) /*-{
        marker.setAnimation(null);
    }-*/;

    private void processSavedOrUpdatedItem(ItemOnMap item) {
        if(isItemLoad(item))
            updateExistedItem(item);
        else {
            storeLoadItem(item);
            updateExistedItem(item);
        }
    }

    private void addCreatedItem(ItemOnMap created_item) {
		HasLatLng map_center = map_view.getMap().getCenter();
		created_item.setLattitude(map_center.getLatitude());
		created_item.setLongtitude(map_center.getLongitude());
		addItem(created_item);
	}

	@Override
	protected void attachEventToMarker(final ItemOnMap item) {
		super.attachEventToMarker(item);	//To change body of overridden methods use File | Settings | File Templates.
        TypedItemHolder item_holder = getItemHolder(item);
        final HasMarker item_marker = item_holder.getItemMarker(item);
		Event.addListener(item_marker, "mouseup", new EventCallback() {
			@Override
			public void callback() {

                item.setLattitude(item_marker.getPosition().getLatitude());
				item.setLongtitude(item_marker.getPosition().getLongitude());

				ItemEvent select_event = ItemEventCollection.getCollection().getEvent(ItemEventCollection.EventType.Select);
				select_event.add(item);
				global_event_bus.fireEvent(select_event);
			}
		});
	}

    @Override
    protected void detachEventsFromMarker(HasMarker marker) {
        super.detachEventsFromMarker(marker);    //To change body of overridden methods use File | Settings | File Templates.
        Event.clearListeners(marker, "mouseup");
    }

    @Override
	public void setEventBus(EventBus eb) {
		setGlobalEventBus(eb);
	}

	@Override
	public void onStop() {

	}

	@Override
	public Widget asWidget() {
		return map_view.asWidget();
	}
}
